/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/




#if !defined(AFX_PGLAREA2D_H__780D0550_350D_4969_A136_10120D3C2703__INCLUDED_)
#define AFX_PGLAREA2D_H__780D0550_350D_4969_A136_10120D3C2703__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLCoord2D.h>
#include <pgl/core/PGLUtility.h>

/*! \brief A polymorphic rectangle.
	\ingroup PGLBasicGroup

  This class describes a rectangular area. The area is
  characterized by
	- an anchor point,
	- a width,
	- a height

   The anchor point is the base class CPGLCoord2D and it's posistion is defined
   by the enumeration EAnchorType (four corners of the are).

   The width and height can defined in 4 different spaces defined in EAreaType enumeration.

*/
class PGLCORE_EXT_CLASS CPGLArea2D : public CPGLCoord2D  
{
PGL_DECLARE_DYNCREATE(CPGLArea2D);
public:
	//! Type of width, height coordinates 
	enum EAreaType 
	{	
		//! World coordinates
		CoordWorld=0, 
		//! Normalized coordinates with respect to the world view
		CoordNorm=1, 
		//! Normalized coordinates with respect to the clipping view
		CoordNormClip=2, 
		//! Bounding box (pixels) coordinates
		CoordBB=3 
	};

	//! Anchor position
	enum EAnchorType
	{
		//! Lower left of pave
		AnchorLowerLeft=0,
		//! Lower right
		AnchorLowerRight=1,
		//! Upper left
		AnchorUpperLeft=2,
		//! Upper right
		AnchorUpperRight=3
	};

public:
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLArea2D(double _llx = 0, double _lly = 0,  double _width = 1, double _height = 1, 
		ECoord2DType _posType = Coord2DNorm, EAreaType _type = CoordNorm, EAnchorType _anchor = AnchorLowerLeft);
	//! Copy constructor
	CPGLArea2D(const CPGLArea2D& a)	{*this=a;};
	//! Assignment constructor
	CPGLArea2D& operator = (const CPGLArea2D& a);
	//! Destructor
	virtual ~CPGLArea2D();
	//@}

	//!\name Anchor
	//@{
	/*! \brief Returns the anchor type.
	\sa EAnchorType
	*/
	//! Returns the anchor position
	EAnchorType GetAnchorType() const			{	return m_eAnchor;};
	/*! \brief Sets the anchor type.
	\sa EAnchorType
	*/
	void SetAnchorType( EAnchorType eAnchor)	{	m_eAnchor = eAnchor;};
	//@}

	//! \name Area dimension
	//@{
	//! Set the area width, height and coordinate space
	void SetArea(const CPGLRectD& rBBox, EAreaType _type = CoordNorm );
	//! Set the area width, height and coordinate space
	void SetArea(double _width, double _height, EAreaType _type = CoordNorm );
	//! Resize the area to match the width, height in the specified coordinate space
	void Resize(gfxinterface::CGfxInterface& gfx, double dWidth, double dHeight, EAreaType type  = CoordBB);
	//@}

	//! \name Rect Getters
	//@{
	//! Returns the bounding box in screen coordinates for the current gfx state
	CPGLRectD GetScreenBBox(const gfxinterface::CGfxInterface& gfx) const;
	//! Returns the dimension (width, height) in screen (pixels) coordinates for the current gfx state
	gfxinterface::SPointD GetScreenSize(const gfxinterface::CGfxInterface& gfx) const;
	//! Returns the bounding box in world coordinates for the current gfx state
	CPGLRectD GetWorldBBox(const gfxinterface::CGfxInterface& gfx) const;
	//! Returns the dimension in world coordinates for the current gfx state
	gfxinterface::SPointD GetWorldSize(const gfxinterface::CGfxInterface& gfx) const;

	CPGLRectD GetWorldRectFromAnchor(const gfxinterface::SPointD& point,const gfxinterface::SPointD& size) const;
	CPGLRectD GetScreenRectFromAnchor(const gfxinterface::CGfxInterface& gfx, const gfxinterface::SPointD& point,const gfxinterface::SPointD& size) const;
	//! Returns current bouding box, in the current coordinate space
	CPGLRectD GetBBox() const;
	//@}

	//!\name Mouse Handling
	//@{
	//! Test if point (screen coordinates) is in the area
	bool IsPointInside(gfxinterface::CGfxInterface& gfx, const CPGLPointD& point) {		return GetScreenBBox(gfx).IsInside(point);};
	//@}

	//! \name Serialization and debugging
	//@{
	//! Serialization
	void SerializeXML( CPGLArchive& ar);
	//! Converts string to AreaType
	static EAreaType StringToAreaType(LPCTSTR szAreaType);
	//! Converts area type to string
	static CString AreaTypeToString(EAreaType eAreaType);
	//! Converts string to anchor type
	static EAnchorType StringToAnchorType(LPCTSTR szAnchorType);
	//! Converts anchor type to string
	static CString AnchorTypeToString(EAnchorType eAnchorType);

	#ifdef _DEBUG
		//! MFC Dump
	    virtual void Dump( CDumpContext& dc ) const;
		//! MFC AssertValid
	    virtual void AssertValid() const;    // Override
	#endif
	//@}

protected:
	//! \name Attributes
	//@{
	//! Anchor type
	EAnchorType m_eAnchor;
	//! Area type
	EAreaType m_eType;
	//! Width
	double m_dWidth;
	//! Height
	double m_dHeight;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLArea2D );
#endif // !defined(AFX_PGLAREA2D_H__780D0550_350D_4969_A136_10120D3C2703__INCLUDED_)
